#!/usr/bin/env python

import unittest
import validate
from google.appengine.ext import db
import os

import tables
import main
import datetime

import tables


origQueries = dict()

class UnitTests(unittest.TestCase) :
    """
    Test that validations for all feilds are functioning as expected
    """
    def testA1TableIntegrityPart1(self):
        '''
        Named such that it will be run first in line of tests, populates global dict
        which will be verified against in last test to ensure tables not modified by tests.
        '''
        for tableName in tables.names:            
            origQueries[tableName] = [row for row in db.GqlQuery("SELECT * FROM " + tableName)]
        
        self.assert_(len(origQueries) == len(tables.names))

    
    def testQuickSearchValidation(self) :
        '''
        Test validates that the quicksearch can have anything
        '''
        self.assert_(not validate.quickSearch("", "tas")) #blank not fine
        self.assert_(not validate.quickSearch("", "classes")) #blank not fine
        self.assert_(validate.quickSearch(r"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-0987654321", "tas")) #all chars should be fine
        self.assert_(not validate.quickSearch(searchString="foo", searchFor = "foobar")) #must search for either Ta's or Classes
    
    def testDropDownValidation(self) :
        '''
        Tests to make sure a dropdown value does not have "--make selection--" or empty
        '''
        self.assert_(not validate.dropDown("--make selection--"))
        self.assert_(not validate.dropDown(""))
        self.assert_(validate.dropDown("foo foo foo"))
        
    def testValidateDigit(self) :
        '''
        Tests validate to make sure that there are 2 numbers and no characters
        '''
        self.assert_(validate.digit("5")) #default count of 1
        self.assert_(validate.digit("55", count=2)) #2 numbers  when count=2
        self.assert_(not validate.digit("5", count=2)) #must be right count
        self.assert_(not validate.digit("abcd", count=4)) #if there are any letters, it should not pass
        self.assert_(not validate.digit("123c", count=4)) #if there are any letters, it should not pass
                
    def testValidateEmail(self) :
        '''
        Tests validateEmail to make sure that a valid email is provided
        '''
        self.assert_(validate.validateEmail("agheinz@mail.utexas.edu")) #my email should pass
        self.assert_(not validate.validateEmail("invalid.utexas.edu")) #no @ sign
        self.assert_(not validate.validateEmail("a@u.e")) #too short
    
    def testValidateFirstName(self) :
        '''
        Tests validateFirstName to make sure that a valid first name is provided
        '''
        self.assert_(validate.validateFirstName("Mary")) #should pass
        self.assert_(validate.validateFirstName("mary")) #not capitolized is okay
        self.assert_(validate.validateFirstName("McPhereson")) #has caps in middle okay
        self.assert_(not validate.validateFirstName("DROP TABLE INSTRUCTORS Mary")) #multiple words w/ whitespace wont pass
        self.assert_(not validate.validateFirstName("O'Donald")) #only irish LAST names may have an apostrophe, not first

    def testValidateLastName(self) :    
        '''
        Tests validateLastName to make sure that a valid last name is provided
        '''
        self.assert_(validate.validateLastName("Mary")) #should pass
        self.assert_(validate.validateLastName("mary")) #not capitolized is okay
        self.assert_(validate.validateLastName("McPhereson")) #has caps in middle okay
        self.assert_(not validate.validateLastName("DROP TABLE INSTRUCTORS Mary")) #multiple words w/ whitespace wont pass
        self.assert_(validate.validateLastName("O'Donald")) #only irish LAST names may have an apostrophe, not first
        
    def testValidateCourseNumber(self) :
        '''
        Tests validateCourseNumber to make sure that a valid course number is provided
        '''
        self.assert_(validate.validateCourseNumber("cs346")) #should pass
        self.assert_(validate.validateCourseNumber("cs397")) #should pass
        self.assert_(not validate.validateCourseNumber("cs3975")) #too many numbers
        self.assert_(not validate.validateCourseNumber("cs842")) #first number out of range
        self.assert_(not validate.validateCourseNumber("cv142")) #does not begin with cs
        self.assert_(not validate.validateCourseNumber("DROP TABLE INSTRUCTORS cs345")) #this is bad
        self.assert_(not validate.validateCourseNumber("cs345 DROP TABLE INSTRUCTORS ")) #this is bad

    def testValidateUniqueNumber(self) :
        '''
        Tests validateUniqueNumber to make sure that a valid unique number is provided
        '''
        self.assert_(validate.validateUniqueNumber("64364")) #should pass
        self.assert_(validate.validateUniqueNumber("01235")) #should pass
        self.assert_(not validate.validateUniqueNumber("cs3977")) #has letters
        self.assert_(not validate.validateUniqueNumber("842")) #not enough numbers
        self.assert_(not validate.validateUniqueNumber("325661429")) #too many numbers
        self.assert_(not validate.validateUniqueNumber("DROP TABLE INSTRUCTORS 76777")) #this is bad
        self.assert_(not validate.validateUniqueNumber("76777 DROP TABLE INSTRUCTORS ")) #this is bad

    def testValidateEid(self) :
        '''
        Tests validateEid
        '''
        self.assert_(validate.validateEid("crc779")) #should pass
        self.assert_(validate.validateEid("cr779")) #should pass
        self.assert_(validate.validateEid("cs3977"))
        self.assert_(not validate.validateEid("842")) #no letters
        self.assert_(not validate.validateEid("cs39")) #too few numbers

    def testValidateNumStudents(self) :
        '''
        Tests validateNumStudents to make sure that a valid number of students is provided
        '''
        self.assert_(validate.validateNumStudents("1")) #should pass
        self.assert_(validate.validateNumStudents("999")) #should pass
        self.assert_(not validate.validateNumStudents("0")) #why have a class?
        self.assert_(not validate.validateNumStudents("1000")) #to many students
        self.assert_(not validate.validateNumStudents("c34")) #has letters
        self.assert_(not validate.validateUniqueNumber("DROP TABLE INSTRUCTORS 45")) #this is bad
        self.assert_(not validate.validateUniqueNumber("45 DROP TABLE INSTRUCTORS ")) #this is bad

    def testValidateNumTas(self) :
        '''
        Tests validateNumTas to make sure that a valid number of tas is provided
        '''
        self.assert_(validate.validateNumTas("4")) #should pass
        self.assert_(validate.validateNumTas("0")) #should pass
        self.assert_(not validate.validateNumTas("6.0")) #no partial ta's (downing clarified)
        self.assert_(not validate.validateNumTas("17")) 
        self.assert_(not validate.validateNumTas("DROP TABLE INSTRUCTORS 8")) #this is bad
        self.assert_(not validate.validateNumTas("8 DROP TABLE INSTRUCTORS")) #this is bad
        
    def testValidateNoIntersection(self) :
        '''
        Test validateNoIntersection to make sure that two exclusive sets don't contain the same element
        '''
        newSeason = tables.Season( name = "Spring" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()        
        self.assert_(validate.validateNoIntersection(set((1,3,5,7,9)),set((2,4,6,8,10))))
        self.assert_(not validate.validateNoIntersection(set((1,3,5,7,9)),set((1,3,5,7,9))))
        self.assert_(not validate.validateNoIntersection(set((1,3,5,7,9)),set((1,4,6,8,10))))
        db.delete(semester)
        db.delete(newSeason)

    def testValidateUniqueCourse(self):
        '''
        Test validateUniqueCourse functionality.
        '''
        newCourse = tables.Course( name = "Intro to FoodLogic", identifier = "CS378" )
        newCourse.put()
        self.assert_(not validate.validateUniqueCourse("CS378", "intro to foodlogic" ))
        self.assert_(not validate.validateUniqueCourse( "cs379", "intro to foodlogic" ))
        self.assert_( validate.validateUniqueCourse( "CS378", "Introduction to foodLogic Practices"))
        self.assert_(not validate.validateUniqueCourse( "CS378" , "inTRo to foodloGIC"))
        newCourse.delete()

    def testValidateUniqueMajor(self):
        '''
        Test validateUniqueMajor functionality.
        '''
        newMajor = tables.Major( name = "Liberal Arts")
        newMajor.put()
        self.assert_(not validate.validateUniqueMajor("liberal arts" ))
        self.assert_( validate.validateUniqueMajor("liberalarts" ))
        self.assert_( validate.validateUniqueMajor("liberal arts undeclared"))
        self.assert_(not validate.validateUniqueMajor("LiBerAl ARTS" ))
        db.delete(newMajor)

    def testValidateUniqueSpecialization(self):
        '''
        Test validateUniqueSpecialization functionality.
        '''
        newS = tables.Specialization( name = "Graph Theory")
        newS.put()
        self.assert_(not validate.validateUniqueSpecialization("graph theory" ))
        self.assert_( validate.validateUniqueSpecialization("graphtheory" ))
        self.assert_( validate.validateUniqueSpecialization("grappling hooks"))
        self.assert_(not validate.validateUniqueSpecialization("GRAPH theory" ))
        db.delete(newS)

    def testValidateUniqueLanguage(self):
        '''
        Test validateUniqueLanguage functionality.
        '''
        newPL = tables.Language( name = "c#")
        newPL.put()
        self.assert_(not validate.validateUniqueLanguage("C#" ))
        self.assert_( validate.validateUniqueLanguage("c3" ))
        self.assert_( validate.validateUniqueLanguage("cc#"))
        self.assert_(not validate.validateUniqueLanguage("c#") )
        db.delete(newPL)

    def testValidateUniqueUnique(self):
        '''
        Test validateUniqueUnique functionality.
        '''
        newSeason = tables.Season( name = "Summer" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        otherSemester = tables.Semester(season = newSeason.key(), year = 2019)
        otherSemester.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman", eid='foobar')
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 54321, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        self.assert_(not validate.validateUniqueUnique("54321", newSemester ))
        self.assert_( validate.validateUniqueUnique("54321", otherSemester ))
        self.assert_( validate.validateUniqueUnique("12345", newSemester ))
        self.assert_( validate.validateUniqueUnique("543211", newSemester))
        self.assert_( validate.validateUniqueUnique("11111" , newSemester))
        db.delete(newSeason)
        db.delete(newSemester)
        db.delete(newCourse)
        db.delete(newInstructor)
        db.delete(newSection)
        db.delete(otherSemester)


    #Here begin the new unitTests that test the datastore
    def testSeasonTable(self) :
        '''
        Tests for season table
        '''
        newSeason = tables.Season( name = "Christmas!" )
        newSeason.put()
        seasons = dict()
        for row in db.GqlQuery("SELECT * FROM Season"): seasons[row.name] = row
        self.assert_("Christmas!" in seasons)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas!")
        db.delete(q)
        seasons = dict()
        for row in db.GqlQuery("SELECT * FROM Season"): seasons[row.name] = row
        self.assert_(not "Christmas!" in seasons)

    def testMajorTable(self) :
        '''
        Tests for major table
        '''
        newMajor = tables.Major( name = "EE" )
        newMajor.put()
        majors = dict()
        for row in db.GqlQuery("SELECT * FROM Major"): majors[row.name] = row
        self.assert_("EE" in majors)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :name", name = "EE")
        db.delete(q)
        majors = dict()
        for row in db.GqlQuery("SELECT * FROM Major"): majors[row.name] = row
        self.assert_(not "EE!" in majors)

    def testTime(self) :
        '''
        Tests for time table
        '''
        newTime = tables.Time( name = "adminMatching" )
        newTime.put()
        time = dict()
        for row in db.GqlQuery("SELECT * FROM Time"): time[row.name] = row
        self.assert_("adminMatching" in time)
        q = db.GqlQuery("SELECT * FROM Time WHERE name = :name", name = "adminMatching")
        db.delete(q)
        time = dict()
        for row in db.GqlQuery("SELECT * FROM Time"): time[row.name] = row
        self.assert_(not "adminMatching!" in time)

    def testAppState(self) :
        '''
        Tests for time table
        '''
        newSeason = tables.Season( name = "Fall" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newTime = tables.Time( name = "adminMatching" )
        newTime.put()
        newAppState = tables.AppState( semester = newSemester.key(), time = newTime.key() )
        newAppState.put()
        appStates = dict()
        for row in db.GqlQuery("SELECT * FROM AppState"): appStates[row.semester.season.name] = row.time.name
        self.assert_("Fall" in appStates)
        q = db.GqlQuery("SELECT * FROM AppState WHERE time = :name", name = newTime)
        db.delete(q)
        appStates = dict()
        for row in db.GqlQuery("SELECT * FROM AppState"): appStates[row.semester.season.name] = row.time.name
        self.assert_(not "Fall" in appStates)
        newSemester.delete()
        newSeason.delete()

    def testSection(self):
        '''
        Tests for Section table
        '''
        newSeason = tables.Season( name = "Summer" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman", eid='foobar')
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 54321, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        sections = dict()
        for row in db.GqlQuery("SELECT * FROM Section"): sections[row.uniqueNumber] = row.numStudents
        self.assert_(54321 in sections)
        
        newSection.delete()
        sections = dict()
        for row in db.GqlQuery("SELECT * FROM Section"): sections[row.uniqueNumber] = row.numStudents
        self.assert_(not 54321 in sections)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)        
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Summer")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        db.delete(q)

    def testInstructorPref(self) :
        '''
        Tests for InstructorPref table
        '''
        #newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman" )
        #newInstructor.put()
        newSeason = tables.Season( name = "Fall" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman", eid='foobar')
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 12345, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        newSpecialization = tables.Specialization( name = "Hackysack" )
        newSpecialization.put()
        newInstructorPref = tables.InstructorPref(section = newSection.key(), nativeEnglish = True, specialization = newSpecialization.key())
        newInstructorPref.put()
        instructorPrefs = dict()
        #for row in db.GqlQuery("SELECT * FROM InstructorPref"): instructorPrefs[row.instructor.firstName] = row.instructor.lastName
        #self.assert_("Popeye" in instructorPrefs)
        #q = db.GqlQuery("SELECT * FROM InstructorPref WHERE instructor = :instructor", instructor = newInstructor)
        #db.delete(q)
        instructorPrefs = dict()
        #for row in db.GqlQuery("SELECT * FROM InstructorPref"): instructorPrefs[row.instructor.firstName] = row.instructor.lastName
        #self.assert_(not "Popeye" in instructorPrefs)
        #q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        #db.delete(q)
        newSection.delete()
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)        
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Fall")
        db.delete(q)
        newCourse.delete()
        q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Specialization WHERE name = :name", name = "Hackysack")
        db.delete(q)
        newInstructorPref.delete()

    def testTaSection(self) :
        '''
        Tests for TaSection table
        '''
        newSeason = tables.Season( name = "Summer" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman", eid='foobar' )
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 54321, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        newSeason2 = tables.Season( name = "Christmas" )
        newSeason2.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        newMajor = tables.Major( name = "Engineering" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = semester.key())
        newTa.put()
        newTaSection = tables.TaSection( section = newSection.key(), ta = newTa.key() )
        newTaSection.put()
        taSections = dict()
        for row in db.GqlQuery("SELECT * FROM TaSection"): taSections[row.ta.firstName] = row.ta.lastName 
        self.assert_("Amelia" in taSections)
        q = db.GqlQuery("SELECT * FROM TaSection WHERE section = :section", section = newSection)
        db.delete(q)
        taSections = dict()
        for row in db.GqlQuery("SELECT * FROM TaSection"): taSections[row.ta.firstName] = row.ta.lastName 
        self.assert_(not "Amelia" in taSections)
        q = db.GqlQuery("SELECT * FROM Ta WHERE email = :email", email = "amelia@example.com")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason2.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineering")
        db.delete(q)
        newSection.delete()
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)        
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Summer")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        db.delete(q)
        
    def testTaQualification(self) :
        '''
        Tests for taQualification table
        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        newMajor = tables.Major( name = "Engineering" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = semester.key())
        newTa.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newTaQualification = tables.TaQualification( qualification = newCourse, ta = newTa )
        newTaQualification.put()
        taQuals = dict()
        for row in db.GqlQuery("SELECT * FROM TaQualification"): 
            taQuals[row.qualification.name] = row.qualification.identifier
        self.assert_("Intro to Security" in taQuals)
        q = db.GqlQuery("SELECT * FROM TaQualification WHERE qualification = :qualification", qualification = newCourse)
        db.delete(q)
        taQuals = dict()
        for row in db.GqlQuery("SELECT * FROM TaQualification"): taQuals[row.qualification.name] = row.qualification.identifier 
        self.assert_(not "Intro to Security" in taQuals)
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Ta WHERE email = :email", email = "amelia@example.com")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineering")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Section WHERE course = :course", course = newCourse)
        db.delete(q)        

    def testSemesterTable(self) :
        '''
        Tests for semester table
        '''
        newSeason = tables.Season( name = "Spring" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        semesters = dict()
        for row in db.GqlQuery("SELECT * FROM Semester"): semesters[row.season.name] = row.year
        self.assert_("Spring" in semesters)

        semesters = dict()
        for row in db.GqlQuery("SELECT * FROM Semester"): semesters[row.season] = row.year
        self.assert_(not newSeason in semesters)
        semester.delete()
        newSeason.delete()


    def testCourseTable(self) :
        '''
        Tests for course table
        '''
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        courses = dict()
        for row in db.GqlQuery("SELECT * FROM Course"): courses[row.name] = row.identifier
        self.assert_("Intro to Security" in courses)
        self.assert_(courses["Intro to Security"] == "cs378")
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        courses = dict()
        for row in db.GqlQuery("SELECT * FROM Course"): courses[row.name] = row.identifier
        self.assert_(not "Intro to Security" in courses)

    def testSpecializationTable(self) :
        '''
        Tests for specialization table
        '''
        newSpecialization = tables.Specialization( name = "Hackysack" )
        newSpecialization.put()
        specialization = dict()
        for row in db.GqlQuery("SELECT * FROM Specialization"): specialization[row.name] = row
        self.assert_("Hackysack" in specialization)
        q = db.GqlQuery("SELECT * FROM Specialization WHERE name = :name", name = "Hackysack")
        db.delete(q)
        specialization = dict()
        for row in db.GqlQuery("SELECT * FROM Specialization"): specialization[row.name] = row
        self.assert_(not "Hackysack" in specialization)       

    def testLanguageTable(self) :
        '''
        Tests for language table
        '''
        newLanguage = tables.Language( name = "Hackysack" )
        newLanguage.put()
        language = dict()
        for row in db.GqlQuery("SELECT * FROM Language"): language[row.name] = row
        self.assert_("Hackysack" in language)
        q = db.GqlQuery("SELECT * FROM Language WHERE name = :name", name = "Hackysack")
        db.delete(q)
        language = dict()
        for row in db.GqlQuery("SELECT * FROM Language"): language[row.name] = row
        self.assert_(not "Hackysack" in language)

    def testInstructorTable(self) :
        '''
        Tests for course table
        '''
        newInstructor1 = tables.Instructor( firstName = "Popeye", lastName = "Sailorman" , eid='foobar')
        newInstructor1.put()
        instructors = dict()
        for row in db.GqlQuery("SELECT * FROM Instructor"): instructors[row.firstName+row.lastName+row.eid] = row
        self.assert_('PopeyeSailormanfoobar' in instructors)
        newInstructor1.delete()

    def testCourseTable(self) :
        '''
        Tests for course table
        '''
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        courses = dict()
        for row in db.GqlQuery("SELECT * FROM Course"): courses[row.name] = row.identifier
        self.assert_("Intro to Security" in courses)
        self.assert_(courses["Intro to Security"] == "cs378")
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        courses = dict()
        for row in db.GqlQuery("SELECT * FROM Course"): courses[row.name] = row.identifier
        self.assert_(not "Intro to Security" in courses)        

    def testTaTable(self) :
        '''
        Tests for TA table

        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        newMajor = tables.Major( name = "Engineeringfoo" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = semester.key())
        newTa.put()
        tas = dict()
        for row in db.GqlQuery("SELECT * FROM Ta"): tas[row.lastName + ", " + row.firstName] = row.email
        self.assert_("Harrison, Amelia" in tas)
        self.assert_(tas["Harrison, Amelia"] == "amelia@example.com")
        q = db.GqlQuery("SELECT * FROM Ta WHERE email = :email", email = "amelia@example.com")
        db.delete(q)
        tas = dict()
        for row in db.GqlQuery("SELECT * FROM Ta"): tas[row.lastName + ", " +  row.firstName] = row.email
        self.assert_(not "Harrison, Amelia" in tas)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineeringfoo")
        db.delete(q)
        
    def testTaLangaugeTable(self):
        '''
        test many-to-many association table taLangauge
        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        newMajor = tables.Major( name = "Engineeringfoo" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = semester.key())
        newTa.put()
        tas = dict()
        testLanguage = tables.Language(name = 'testLanguage')
        testLanguage.put()
        
        testTaLanguage = tables.TaLanguage(language = testLanguage, ta = newTa)
        testTaLanguage.put()
        
        tlDict = dict()
        q = db.GqlQuery("SELECT * FROM TaLanguage WHERE language = :testLang", testLang = testLanguage)
        mylist = [row for row in q]
        self.assert_(len(mylist) == 1)
        result = mylist[0]
        self.assert_(result.language.name == testLanguage.name)
        
        testTaLanguage.delete()
        testLanguage.delete()        
        q = db.GqlQuery("SELECT * FROM Ta WHERE email = :email", email = "amelia@example.com")
        db.delete(q)
        tas = dict()
        for row in db.GqlQuery("SELECT * FROM Ta"): tas[row.lastName + ", " +  row.firstName] = row.email
        self.assert_(not "Harrison, Amelia" in tas)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineeringfoo")
        db.delete(q)

    def testTaTaHistoryTable(self) :
        '''
        Test for TaTaHistory table
        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        semester = tables.Semester(season = newSeason.key(), year = 2045)
        semester.put()
        newMajor = tables.Major( name = "Engineeringfoo" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = semester.key())
        newTa.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        testTaTaHistory = tables.TaTaHistory(taHistory = newCourse, ta = newTa)
        testTaTaHistory.put()
        taHists = dict()
        for row in db.GqlQuery("SELECT * FROM TaTaHistory") : taHists[row.ta.firstName] = row.taHistory.name
        self.assert_("Amelia" in taHists)
        self.assert_(taHists["Amelia"] == "Intro to Security")
        q = db.GqlQuery("SELECT * FROM TaTaHistory WHERE ta = :ta", ta = newTa)
        db.delete(q)        
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Ta WHERE firstName = :firstName", firstName = "Amelia")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineeringfoo")
        db.delete(q)

    def testWantedTaInstructorPref(self):
        '''
        Test for WantedTaInstructorPref
        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newMajor = tables.Major( name = "Engineeringfoo" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = newSemester.key())
        newTa.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman", eid='foobar')
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 12345, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        newSpecialization = tables.Specialization( name = "Hackysack" )
        newSpecialization.put()
        newInstructorPref = tables.InstructorPref(section = newSection.key(), nativeEnglish = True, specialization = newSpecialization.key())
        newInstructorPref.put()
        newWantedTaInstructorPref = tables.WantedTaInstructorPref(instructorPref = newInstructorPref, ta = newTa)
        newWantedTaInstructorPref.put()
        wanted = dict()
        for row in db.GqlQuery("SELECT * FROM WantedTaInstructorPref") : wanted[row.ta.firstName] = row
        self.assert_("Amelia" in wanted)
        q = db.GqlQuery("SELECT * FROM WantedTaInstructorPref WHERE instructorPref = :instructorPref", instructorPref = newInstructorPref)
        db.delete(q)        
        newSection.delete()
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Specialization WHERE name = :name", name = "Hackysack")
        db.delete(q)
        newInstructorPref.delete()
        q = db.GqlQuery("SELECT * FROM Ta WHERE firstName = :firstName", firstName = "Amelia")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineeringfoo")
        db.delete(q)

    def testUnwantedTaInstructorPref(self):
        '''
        Test for UnwantedTaInstructorPref
        '''
        newSeason = tables.Season( name = "Christmas" )
        newSeason.put()
        newSemester = tables.Semester(season = newSeason.key(), year = 2045)
        newSemester.put()
        newMajor = tables.Major( name = "Engineeringfoo" )
        newMajor.put()
        newTa = tables.Ta(firstName = "Amelia", lastName = "Harrison", phone = "51255555555", email = "amelia@example.com", major = newMajor.key(), admissionDate = datetime.date(2005, 12, 25), degree = "Masters", supervisor = "Glenn Downing", residency = True, nativeEnglish = True, taHistory = True, semester = newSemester.key())
        newTa.put()
        newCourse = tables.Course( name = "Intro to Security", identifier = "cs378" )
        newCourse.put()
        newInstructor = tables.Instructor( firstName = "Popeye", lastName = "Sailorman" , eid='foobar')
        newInstructor.put()
        newSection = tables.Section( uniqueNumber = 12345, course = newCourse.key(), instructor = newInstructor.key(), numTas = 2, numStudents = 76, semester = newSemester.key())
        newSection.put()
        newSpecialization = tables.Specialization( name = "Hackysack" )
        newSpecialization.put()
        newInstructorPref = tables.InstructorPref(section = newSection.key(), nativeEnglish = True, specialization = newSpecialization.key())
        newInstructorPref.put()
        
        newUnwantedTaInstructorPref = tables.UnwantedTaInstructorPref(instructorPref = newInstructorPref, ta = newTa)
        newUnwantedTaInstructorPref.put()
        Unwanted = dict()
        for row in db.GqlQuery("SELECT * FROM UnwantedTaInstructorPref") : Unwanted[row.ta.firstName] = row
        self.assert_("Amelia" in Unwanted)
        q = db.GqlQuery("SELECT * FROM UnwantedTaInstructorPref WHERE instructorPref = :instructorPref", instructorPref = newInstructorPref)
        db.delete(q)        
        
        newSection.delete()
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Course WHERE name = :name", name = "Intro to Security")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Instructor WHERE firstName = :firstName", firstName = "Popeye")       
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Specialization WHERE name = :name", name = "Hackysack")
        db.delete(q)
        newInstructorPref.delete()
        q = db.GqlQuery("SELECT * FROM Ta WHERE firstName = :firstName", firstName = "Amelia")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Season WHERE name = :name", name = "Christmas")
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Semester WHERE season = :season", season = newSeason.key())
        db.delete(q)
        q = db.GqlQuery("SELECT * FROM Major WHERE name = :major", major = "Engineeringfoo")
        db.delete(q)
    
        
        
    def testZ9TableIntegrityPart2(self):
        '''
        Named such that it will be run last in line of tests, populates dict
        which will be verified against global dict to ensure tables not modified by tests.
        
        If this tests fails, uncomment the prints and rerun the webTest to see why.
        '''
        afterTests = dict()
        for tableName in tables.names:
            afterTests[tableName] = [row for row in db.GqlQuery("SELECT * FROM " + tableName)]
            #print tableName
            #print '\t', len(origQueries[tableName]), len(afterTests[tableName])
            self.assert_( len(afterTests[tableName]) == len(origQueries[tableName]) )
            
            for i in xrange(len(afterTests[tableName])):
                #print '\t', i, tableName
                self.assert_(afterTests[tableName][i].key() == origQueries[tableName][i].key())

    
        
if (__name__ == "__main__" ) :    

    suite = unittest.TestLoader().loadTestsFromTestCase(UnitTests)
    unittest.TextTestRunner(verbosity=2).run(suite)
